/* James McTaggart (jcm28) Informatics
Multimedia Communications Technology - 17th May 2007
In making this submission I declare that my work contains no examples
of misconduct, such as plagiarism, collusion, or fabrication of results.
*/

package client;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;

public class RadioReceiver extends Thread {

	private DatagramSocket clientSocket;
	private byte[] inData;
	private byte[] outData;
	private int counter;
	private Client client;
	private int sampleCounter;
	private InetAddress serverIP;
	private int serverPort;
	private static Hashtable<Integer, String> codeTable = new Hashtable<Integer, String>();
	
	static{
		codeTable.put(1, "One ");
		codeTable.put(2, "Two ");
		codeTable.put(3, "Three ");
		codeTable.put(4, "Four ");
		codeTable.put(5, "Five ");
		codeTable.put(6, "Six ");
		codeTable.put(7, "Seven ");
		codeTable.put(8, "Eight ");
		codeTable.put(9, "Nine ");
		codeTable.put(10, "Ten ");
		
	}
	
	public RadioReceiver(Client client, InetAddress serverIP, int serverPort) {
		this.client = client;
		this.serverIP = serverIP;
		this.serverPort = serverPort;
		try {
			clientSocket = new DatagramSocket();
			inData = new byte[60];
			outData = new byte[60];
			counter = 1;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		try {
			//Send the greeting packet so that the radio server can get a IP and port
			clientSocket.send(ClientProtocol.get301(serverIP, serverPort));
			
			
			DatagramPacket inPacket = new DatagramPacket(inData, inData.length);
			// Receiver the first sample and start the sample counter
			// Sample counter subsequently used to track missing samples
			clientSocket.receive(inPacket);
			String in = new String(inPacket.getData());
			sampleCounter = getSampleNo(in);
			client.addSample(new Sample(sampleCounter, in));

			int tempCounter;
			while (true) {
				clientSocket.receive(inPacket);
				in = new String(inPacket.getData());
				//client.print("From receiver>"+in);
				switch (getMessageID(in)) {
				case -1:
					break;
				case 401:
					// A sample received. check it's in order and add etc.
					tempCounter = getSampleNo(in);
					if (tempCounter != sampleCounter + 1) {
						//Currently supports retransmission of 1 missing packet only requested once
						//Always assumes that it was just the last packet that is missing
						//Does not attempt to track the retransmit request
						clientSocket.send(ClientProtocol.get302(tempCounter-1,serverIP,serverPort));
					}
					sampleCounter = tempCounter;
					client.addSample(new Sample(sampleCounter, in));
					break;

				case 402:
					// A retransmitted sample
					sampleCounter = getSampleNo(in);
					client.addSample(new Sample(sampleCounter,decodeRetransmit(in)));
					break;
				default:break;
				}
				
				// System.out.println(getSampleNo(in));
				// System.out.println("In from Server> Length>"
				// +inPacket.getData().length + " Data>" + in);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static String decodeRetransmit(String message){
		//byte 19 of the packet is a # and then the retransmitted code ends before the
		//next #
		int a = message.indexOf("#");
		int b = message.substring(a+1).indexOf("#");
		String code = message.substring(a+1).substring(0, b);
		StringTokenizer st = new StringTokenizer(code," ");
		String result = message.substring(0, a)+ "#";
		while(st.hasMoreTokens()){
			String s = st.nextToken();
			int c = Integer.parseInt(s);
			result += codeTable.get(c);
		}
		result += "#";
		return result;
	}

	private int getMessageID(String message) {
		try {
			int id = Integer.parseInt(message.substring(0, 3));
			if (id != 401 && id != 402) {
				return -1;
			}
			return id;
		} catch (NumberFormatException e) {
			return -1;
		}
	}

	private int getSampleNo(String sample) {
		String numberString = sample.substring(7, 13);
		return Integer.parseInt(numberString);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//RadioReceiver connector = new RadioReceiver(null, null, 0);
		//connector.start();
		String test = "kjbasfda#1 2 3 4 5#sadsd";
		System.out.println(decodeRetransmit(test));
	}

}
